package com.hzz.framework.fileServer.servlet;

import com.hzz.framework.Response;
import com.hzz.framework.annotation.NoAuthorize;
import com.hzz.framework.fileServer.baidu.ueditor.PathFormat;
import com.hzz.framework.fileServer.config.FileServerProperties;
import com.hzz.framework.util.ValidatorUtil;
import com.hzz.framework.util.WebUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.Map;


/**
 * Servlet implementation class upload
 */
@NoAuthorize
@Slf4j
@RestController
@Api("文件上传")
public class UploadServlet {
    @Autowired
    FileServerProperties fileServer;

    @RequestMapping(method = {RequestMethod.POST}, value = "/file/fileUpload")
    @ResponseBody
    @ApiOperation(value = "文件上传fileUpload", notes = "Content-Type:multipart/form-data\n" +
            "dir:string 上传文件类型（图片image，音频audio，多媒体media，普通文件file\n" +
            "file:File 文件流）")
    protected Response fileUpload(HttpServletRequest request) throws Exception {
        log.info("UploadServlet fileUpload");
        Response result = new Response(0, "success");
        String contentType = request.getHeader("Content-Type");
        if (contentType == null || !contentType.startsWith("multipart/form-data")) {
            return Response.error("请将【Content-Type】设置为【multipart/form-data】");
        }

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        // 是否选择了文件
        if (fileMap == null || fileMap.size() == 0) {
            return Response.error("请选择文件");
        }
        // 上传文件类型（图片image，音频audio，多媒体media，普通文件file
        String dirName = request.getParameter("dir");
        if (ValidatorUtil.isNullEmpty(dirName)) {
            dirName = "file";
        }
        // 路径变量
        String savePath = fileServer.getUpload() + dirName, remoteUrl = fileServer.getDownload() + dirName;
        // 子文件夹
        String forDate = PathFormat.parse("/{yyyy}{mm}/");
        // 文件保存目录路径
        savePath += forDate;
        // 文件保存目录URL
        remoteUrl += forDate;
        // 创建文件夹
        File saveDirFile = new File(savePath);
        if (!saveDirFile.exists()) {
            saveDirFile.mkdirs();
        }
        // 检查写权限
        if (!saveDirFile.canWrite()) {
            return Response.error("上传目录没有写权限");
        }

//        fileMap.values().parallelStream().filter(fileServer->ValidatorUtil.notEmpty(fileServer.getOriginalFilename())).forEach(fileServer->{
//
//        });

        for (MultipartFile multipartFile : fileMap.values()) {
            String fileName = multipartFile.getOriginalFilename();
            // long fileSize = item.getSize();
            // 上传文件的名称
            if (ValidatorUtil.isNullEmpty(fileName)) {
                return Response.error("上传文件没有文件名");
            }
            // 检查文件大小
            if (!checkFileSize(multipartFile.getSize(), dirName)) {
                return Response.error("上传文件大小超过限制");
            }
            // 检查扩展名
            String fileExt = "." + WebUtil.getFileExt(fileName);
            if (!checkExt(dirName, fileExt)) {
                return Response.error("上传文件扩展名不正确");
            }

            // 创建新的文件名
            String newFileName = WebUtil.getTime("yyyyMMddHHmmss") + WebUtil.getRandomString(5) + fileExt;

            try {
                multipartFile.transferTo(new File(savePath, newFileName));
            } catch (Throwable e) {
                log.error("文件上传异常!", e);
                return Response.error("上传文件失败");
            }

            Map<String, Object> fileData = new HashMap<>();
            fileData.put("name", fileName);
            fileData.put("url", remoteUrl + newFileName);
            result.data = fileData;
        }
        return result;
    }

    /**
     * 检查文件大小
     *
     * @param size 上传文件的大小
     * @param type 上传文件的类型
     */
    private boolean checkFileSize(long size, String type) {
        boolean flag = true;
        if (fileServer.getFileType().getImage().equals(type)) {
            if (size / 1024 / 1024 > fileServer.getFileSize().getImage()) {
                flag = false;
            }
        } else if (fileServer.getFileType().getAudio().equals(type)) {
            if (size / 1024 / 1024 > fileServer.getFileSize().getAudio()) {
                flag = false;
            }
        } else if (fileServer.getFileType().getMedia().equals(type)) {
            if (size / 1024 / 1024 > fileServer.getFileSize().getMedia()) {
                flag = false;
            }
        }
        return flag;
    }

    /**
     * <p>
     * 检查文件扩展名是否合法
     *
     * @param type 上传类型
     * @param ext  文件扩展名
     * @return true:合法 false:不合法
     */
    private boolean checkExt(String type, String ext) {
        if (fileServer.getFileType().getImage().equals(type)) {// 图片
            return fileServer.getFileExt().getImage().contains(ext);
        } else if (fileServer.getFileType().getMedia().equals(type)) {//多媒体
            return fileServer.getFileExt().getMedia().contains(ext);
        } else if (fileServer.getFileType().getAudio().equals(type)) {// 普通文件
            return fileServer.getFileExt().getAudio().contains(ext);
        } else {//其它文件
            return fileServer.getFileExt().getFile().contains(ext);
        }
    }
}
